﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Text;
using System.IO.Ports;
using System.Management;
using System.Collections;

namespace PulseApp
{
    public class Device
    {
        public SerialPort serialPort;
        public Boolean acceptData = true;
        public static byte[] start = { 0x20, 0x32 };
        public static byte[] stop = { 0x20, 0x33 };
        private byte amplifier = 0x04;
        public int did;


        //constructor, import the reference for main form.
        public Device(int deviceId)
        {
            getSerialPorts(deviceId);
            this.did = deviceId;
        }

        //get all ports connecting with PulseWave device
        public SerialPort[] getSerialPorts(int deviceId)
        {
            ManagementClass mc = new ManagementClass("Win32_SerialPort");     //
            ManagementObjectCollection moc = mc.GetInstances();
            SerialPort[] result = null;
            foreach (ManagementObject mo in moc)
            {
                if (mo.GetPropertyValue("Description").ToString().Trim() == "Silicon Labs CP210x USB to UART Bridge")
                {
                    String portId = mo.GetPropertyValue("DeviceID").ToString().Trim();
                    SerialPort aPort = new SerialPort(portId);
                    if (result == null)
                    {
                        result = new SerialPort[1];
                        result[0] = aPort;
                    }
                    else
                    {
                        SerialPort[] temp = new SerialPort[result.Length + 1];
                        for (int i = 0; i < result.Length; i++)
                        {
                            temp[i] = result[i];
                        }
                        temp[result.Length] = aPort;
                        result = temp;
                    }
                }
            }
            if (result != null && result.Length > deviceId) this.serialPort = result[deviceId]; //set the port
            return result;
        }

        public void setSerialPort(String portId)
        {
            this.serialPort = new SerialPort(portId.Trim());
        }



        public void startMonitoring()
        {
            try
            {
                serialPort.Open();
                serialPort.Write(start, 0, 2);
                doAccept();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public void endMonitoring()
        {
            if (this.serialPort != null && this.serialPort.IsOpen)
            {
                this.acceptData = false;
                serialPort.Write(stop, 0, 2);
                serialPort.Close();
                Console.WriteLine("port closed");
            }
        }

        //read a byte from the device and return is as a short
        public short getByte()
        {
            if (this.serialPort!=null && !this.serialPort.IsOpen)
            {
                startMonitoring();
            }
            short shortValues;

            byte[] ReceiveByte = new byte[1];
            try
            {
                int count = serialPort.Read(ReceiveByte, 0, 1);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
            shortValues = (short)ReceiveByte[0];
            return shortValues;
        }

        //read a short(2bytes) from the device;
        public short getShort()
        {
            if (!this.serialPort.IsOpen)
            {
                startMonitoring();
            }
            short shortValues;

            byte[] ReceiveByte = new byte[2];
            
            
            try
            {
                int count = serialPort.Read(ReceiveByte, 0, 2);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
            shortValues = (short)BitConverter.ToUInt16(ReceiveByte, 0);
            return shortValues;
        }


        public void doAccept()
        {
            this.acceptData = true;
        }

        public void notAccept()
        {
            if (this.acceptData == true)
            {
                this.acceptData = false;
                serialPort.Write(stop, 0, 2);
                serialPort.Close();
            }
        }

        public void amplify()
        {
            if (portIsOpened() && this.amplifier >= 0x00 && this.amplifier < 0x0A)
            {
                this.amplifier++;
                byte[] command = { 0x20, 0x34, this.amplifier };
                serialPort.Write(command, 0, 3);
            }
        }


        public void deAmplify()
        {
            if (portIsOpened() && this.amplifier > 0x00 && this.amplifier <= 0x0A)
            {
                this.amplifier--;
                byte[] command = { 0x20, 0x34, this.amplifier };
                serialPort.Write(command, 0, 3);
            }
        }

        public Boolean isReady()
        {
            if (this.serialPort != null)
            {
                return true;
            }
            else{
                return false;
            }
        }

        public Boolean portIsOpened()
        {
            Boolean result = false;
            if (this.serialPort != null)
            {
                result = this.serialPort.IsOpen;
            }
            return result;
        }



    }


}

